<?php

namespace eolinker;

use eolinker\Models\EoApi;
use eolinker\Models\EoApiCache;
use eolinker\Models\EoApiGroup;
use eolinker\Models\EoApiRequestParam;
use eolinker\Models\EoProjectStatusCode;
use eolinker\Models\EoProjectStatusCodeGroup;
use eolinker\Models\EoApiResultParam;

class ApiEoLinkerTool
{
    /**
     * 更新api基本信息
     * @param $data
     * @return EoApi|\think\Model
     */
    public function saveApi($data)
    {
        $api = EoApi::where([
            'apiURI' => $data['apiURI'],
            'projectID' => $data['projectID'],
            'apiRequestType' => $data['apiRequestType'],
        ])->findOrEmpty()->toArray();
        if (!$api) {
            return EoApi::create($data);
        } else {
            EoApi::where([
                'apiURI' => $data['apiURI'],
                'projectID' => $data['projectID'],
                'apiRequestType' => $data['apiRequestType'],
            ])->update($data);

            return EoApi::where([
                'apiURI' => $data['apiURI'],
                'projectID' => $data['projectID'],
                'apiRequestType' => $data['apiRequestType'],
            ])->find();
        }
    }


    /**
     * 创建分组
     * @param array $group
     * @param int $projectID
     * @return mixed
     * @throws \Exception
     */
    public function createGroup(array $group, int $projectID)
    {
        if (empty($group)) {
            throw new \Exception('缺少api接口分组信息');
        }

        // 写入订单数据
        $detail = [];
        EoApiGroup::transaction(function () use ($group, $projectID, &$detail) {
            $pid = 0;
            foreach ($group as $k => $g) {
                $data = ['groupName' => $g, 'projectID' => $projectID, 'parentGroupID' => $pid];
                $group = EoApiGroup::where($data)->findOrEmpty()->toArray();
                if (!$group) {
                    $data = array_merge($data, ['isChild' => $k]);
                    $groupId = EoApiGroup::insertGetId($data);
                } else {
                    EoApiGroup::where('groupID', $group['groupID'])->update(['isChild' => $k]);
                    $groupId = $group['groupID'];
                }
                $detail = EoApiGroup::where('groupID', $groupId)->findOrEmpty();
                $pid = $groupId;
            }
        });

        return $detail;
    }


    /**
     * 创建接口缓存
     * @param $apiID
     * @return array|EoApiCache|false|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function createCache($apiID)
    {
        if (!$api = EoApi::find($apiID)->toArray()) {
            return false;
        }
        $cacheJson['baseInfo'] = array_intersect_key($api, array_flip(['apiName', 'apiURI', 'apiProtocol', 'apiSuccessMock', 'apiFailureMock', 'apiRequestType', 'apiStatus', 'starred', 'apiNoteType', 'apiNoteRaw', 'apiNote', 'apiRequestParamType', 'apiRequestRaw', 'apiUpdateTime', 'apiFailureStatusCode', 'apiSuccessStatusCode', 'beforeInject', 'afterInject']));
        $cacheJson['headerInfo'] = [];
        $cacheJson['mockInfo'] = [];
        $cacheJson['requestInfo'] = EoApiRequestParam::where('apiId', $apiID)->select()->toArray();
        $cacheJson['resultInfo'] = EoApiResultParam::where('apiId', $apiID)->select()->toArray();

        $cacheJson = json_encode($cacheJson, 256);

        $where = [
            'projectID' => $api['projectID'],
            'apiID' => $apiID,
        ];
        $data = array_merge($where, [
            'groupID' => $api['groupID'],
            'apiJson' => $cacheJson,
            'starred' => 0,
            'updateUserID' => 1
        ]);

        $result = EoApiCache::where($where)->findOrEmpty()
            ->toArray();

        if ($result) {
            EoApiCache::where($where)->update($data);
            return EoApiCache::where($where)->find();
        } else {
            return EoApiCache::create($data);
        }
    }

    /**
     * 创建请求参数
     * @param $data
     * @return mixed
     */
    public function createRequestParam($data)
    {
        $result = EoApiRequestParam::where([
            'apiID' => $data['apiID'],
            'paramKey' => $data['paramKey']
        ])->findOrEmpty()
            ->toArray();

        if ($result) {
            EoApiRequestParam::where([
                'apiID' => $data['apiID'],
                'paramKey' => $data['paramKey']
            ])->update($data);

            return EoApiRequestParam::where([
                'apiID' => $data['apiID'],
                'paramKey' => $data['paramKey']
            ])->find();
        } else {
            return EoApiRequestParam::create($data);
        }
    }

    /**
     * 创建返回参数
     * @param $data
     * @return mixed
     */
    public function createResultParam($data)
    {
        $result = EoApiResultParam::where([
            'apiID' => $data['apiID'],
            'paramKey' => $data['paramKey']
        ])->findOrEmpty()
            ->toArray();

        if ($result) {
            EoApiResultParam::where([
                'apiID' => $data['apiID'],
                'paramKey' => $data['paramKey']
            ])->update($data);

            return EoApiResultParam::where([
                'apiID' => $data['apiID'],
                'paramKey' => $data['paramKey']
            ])->find();
        } else {
            return EoApiResultParam::create($data);
        }
    }

    /**
     * 转换apidoc参数类型值到eolikner
     * @param string|null $type
     * @return mixed
     */
    public function parseParamType(string $type = null)
    {
        $type = strtoupper($type);
        //默认字符串类型
        $typeValue = EoApiRequestParam::PARAM_TYPE_STRING[EoApiRequestParam::ENUM_VALUE];
        //有数组标记 直接返回数组类型
        if (strpos($type, '[]') !== false) {
            return EoApiRequestParam::PARAM_TYPE_ARRAY[EoApiRequestParam::ENUM_VALUE];
        }
        $allType = EoApiRequestParam::enumParamType();
        foreach ($allType as $item) {
            $item['name'] = strtoupper($item['name']);
            if ((strpos($type, $item['name']) !== false) || strpos($item['name'], $type)) {
                $typeValue = $item['value'];
                break;
            }
        }
        return $typeValue;
    }

    /**
     * 创建状态码分组
     * @param string $group
     * @param int $projectID
     * @return mixed
     */
    public function createProjectStatusCodeGroup(string $group, int $projectID)
    {
        return EoProjectStatusCodeGroup::query()->firstOrCreate(['projectID' => $projectID, 'groupName' => $group], ['parentGroupID' => 0, 'isChild' => 0]);
    }

    /**
     * 创建状态码
     * @param int $code 状态码
     * @param string $codeDescription   状态码描述
     * @param int $groupID  分组id
     * @return mixed
     */
    public function createProjectStatusCode(int $code, string $codeDescription, int $groupID)
    {
        return EoProjectStatusCode::query()->updateOrCreate(['code' => $code, 'groupID' => $groupID], ['codeDescription' => $codeDescription]);
    }


}
